package jonaVisual;

import java.awt.*;

import Jona.*;

import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.*;

import javax.swing.*;

import jonaPad.GTimer;

public class VisualJPanel extends JScrollPane implements MouseListener, ActionListener {
	
	VisualObject[] visObjects;
	private VisualObject selected;
	private static int yOffset = 5;
	private static int xOffset = 5;
	private static Color tooltipColor = new Color(255,255,225);
	private JTextArea jta1;

	private JScrollPane jsp1;
	private JTextArea jtf;
	private String tooltip = "";
	private JLabel jl1;
	private boolean showTooltip = false;
	private Point mousePoint;
	private GTimer gt1;
	private long oldTime;
	private boolean moved = false;
	private Icon i1;
	private BufferedImage image;
	private Theory t1;
	private Dimension imageMinimumDimension;
	
	private static Color orangeDark = Color.ORANGE.darker().darker().darker();
	private static Color orangeLight = Color.ORANGE.brighter();
	private static Color greenDark = Color.GREEN.darker().darker().darker();
	private static Color greenLight = Color.GREEN.brighter();
	private static Color redDark = Color.RED.darker().darker().darker();
	private static Color redLight = Color.RED.brighter();
	
	private JMenuItem jmi1,jmi2;
	private JPopupMenu jpm1;
	private JButton support,attack,jbassumption, jbissue;
	private ImageIcon[] images;
	private int useVOTreeMaker = 0;
	
	// Ugly
	char startConditionName = 'A';
	
	// Data for frame Conflict Solver Warning
	JFrame frameCSWarning = new JFrame("Solve Conflict: Warning");
	JFrame frameCS = new JFrame("Solve Conflict");
	JPanel infoPanel = new JPanel();
	JPanel dataPanel = new JPanel();
	JPanel submitPanel = new JPanel();
	Label labelGiveValue = new Label("Geef de waarde van de geselecteerde stelling op:");
	JRadioButton rbutUndefeated = new JRadioButton("Undefeated");
	JRadioButton rbutDefeated = new JRadioButton("Defeated");
	ButtonGroup butgroupDefeasibility = new ButtonGroup();
	JButton buttonSubmit = new JButton("OK");
	
	public VisualJPanel(JTextArea jta1,JButton support, JButton attack, JButton jbissue, JButton jbassumption, int useVOTreeMaker)
	{	
		this.useVOTreeMaker = useVOTreeMaker;
		images = new ImageIcon[2];
		
		// Geen image ingesloten. Moet rechtgetrokken
		images[0] =  new ImageIcon("images/issu.gif");
		images[1] =  new ImageIcon("images/assuption.gif");

		
		this.support = support;
		this.attack =attack;
		support.addActionListener(this);
		attack.addActionListener(this);
		this.jbissue = jbissue;
		this.jbassumption = jbassumption;
		
		jbissue.addActionListener(this);
		jbassumption.addActionListener(this);
		
		this.jta1 = jta1;
		this.verticalScrollBar.setUnitIncrement(5);
		//setLayout(new BorderLayout());		
		image = new BufferedImage(500,
				500,BufferedImage.TYPE_INT_ARGB);
		
		jpm1 = new JPopupMenu("Pop-upper");
		
		jmi1 = new JMenuItem("Add supporter");
		jmi2 = new JMenuItem("Add attacker");
		
		jmi1.setActionCommand("supporter");
		jmi1.addActionListener(this);
		jmi2.setActionCommand("attacker");
		jmi2.addActionListener(this);
		
		jl1 = new JLabel();
		getViewport().add(jl1,BorderLayout.CENTER);
		
		jtf = new JTextArea();
		//jtf.setBounds(10,10,100,100);
		jtf.setBackground(Color.LIGHT_GRAY);
	
		jsp1 = new JScrollPane(jtf);
		add(jsp1);
		jsp1.setVisible(false);
		
		//add(jtf);
		//jtf.setVisible(false);
		gt1 = new GTimer(500,this);
		gt1.start();
		
		ComponentAdapter ca = new ComponentAdapter(){
			public void componentResized(ComponentEvent e)
			{
				//System.out.println("resized!");
				redrawPanel();
			}
		};  
		
		this.addComponentListener(ca);
		MouseMotionAdapter mma = new MouseMotionAdapter(){
			public void mouseMoved(MouseEvent e)
			{
				oldTime = System.currentTimeMillis();
				mousePoint = new Point(e.getX(),e.getY());
				moved = true;
				if(showTooltip)
				{
					showTooltip = false;
					redrawPanel();
				}
			}
		};
		
		this.addMouseMotionListener(mma);
		
		KeyAdapter ka = new KeyAdapter(){
			public void keyPressed(KeyEvent e) 
			{
				if(e.getKeyCode() == 10) enterPressed();
			}
		};	
		//jtf.addKeyListener(ka);
		this.addMouseListener(this);
	}
	
	private void fillPopupMenu(ArgObject ao1, boolean isRecursive)
	{
		jpm1.removeAll();
		
		if(!isRecursive)
		{
			jpm1.add(jmi1);
			jpm1.add(jmi2);
			if(ao1.getArgumentType() != Statement.ASSUMPTION)
			{
				JMenuItem jmi3 = jpm1.add("Make assumption");
				jmi3.setActionCommand("makeAssumption");
				jmi3.addActionListener(this);			
			}
			if(ao1.getArgumentType() != Statement.ISSUE)
			{
				JMenuItem jmi3 = jpm1.add("Make Issue");
				jmi3.setActionCommand("makeIssue");
				jmi3.addActionListener(this);			
			}
		}
		if(!(ao1 instanceof Conditional))
		{
			JMenuItem jmi3 = jpm1.add("Remove statement");
			jmi3.setActionCommand("RemoveStatement");
			jmi3.addActionListener(this);	
		}
		if (ao1.evaluate(t1) == Statement.EVALUATION_UNKNOWN)
		{
		    JMenuItem jmi4 = jpm1.add("Solve conflict");
		    jmi4.setActionCommand("SolveConflict");
		    jmi4.addActionListener(this);
		}
	}
	
	private void makeTooltipText(ArgObject ao1)
	{
		String type = "";
		switch(ao1.getArgumentType())
		{
		case Statement.ASSUMPTION:
			type = "Assumption";
			break;
		case Statement.ISSUE :
			type = "Issue";
			break;
		default:
			type = "Default";
		break;
		
		}
		if(ao1 instanceof Conditional)
			tooltip ="Conditional (" + type  + ")\n\n";
		else if(ao1 instanceof Statement)
			tooltip = "Statement (" + type  + ")\n\n";
		if(ao1.getText().length() > 50)
		{
			String s1 = ao1.getText();
			while(s1.length() > 50)
			{
				tooltip += s1.substring(0,50) + "\n";
				s1 = s1.substring(50,s1.length());
			}
			tooltip+=s1;
			
		}
		else
		{
			tooltip+=ao1.getText();
		}
		
	}
	
	public Theory getVisualTheory()
	{
		return t1;
	}
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource() == gt1)
		{
			if(!showTooltip && !jpm1.isVisible())
			{
				if(System.currentTimeMillis() - oldTime > 1000 && visObjects!= null && mousePoint != null && moved && !jsp1.isVisible())
				{
					//System.out.println("checking");
					int i =0;
					boolean found = false;
					int xScrolled = (this.horizontalScrollBar.getValue());
					int yScrolled = (this.verticalScrollBar.getValue());
					
					while(!found && i < visObjects.length)
					{
						if(visObjects[i].contains(mousePoint.x + xScrolled,mousePoint.y + yScrolled))
						{
							found = true;
							makeTooltipText(visObjects[i].getArgObject());
							if(visObjects[i] instanceof VisualArgObject)
							{
								if(((VisualArgObject)visObjects[i]).isRecursive())
								{
									tooltip += "\n(Recursive Path)";
								}
							}
						}
						i++;
					}
					if(found)
					{
						showTooltip = true;
						//updateIcon();
						setTheory(t1);
						
					}
					moved = false;
				}
			}
			else
			{
				oldTime = System.currentTimeMillis();
			}
		}
		else if(e.getSource() == support)
		{
			
			System.out.println("adding supporter");
			if(selected != null)
			{
				ArgObject ao1 = selected.getArgObject();
				Statement s1 = new Statement();
				s1 = createAndSetName(s1);
				
				Conditional c1 = new Conditional(s1,ao1);
				c1.setName(startConditionName +"");
				startConditionName++;
				
				t1.addStatement(s1);
				t1.addStatement(c1);
				ao1.addedInformation(true);
				doSetTheory(t1, false);
				showEdit(s1);
				support.setEnabled(false);
				attack.setEnabled(false);
			}			
		}
		else if(e.getSource() == attack)
		{
			System.out.println("adding attacker");
			if(selected != null)
			{
				ArgObject ao1 = selected.getArgObject();
				Statement s1 = new Statement();
				s1 = createAndSetName(s1);
				Conditional c1 = new Conditional(s1,ao1.getNegation());
				c1.setName(startConditionName + "");
				startConditionName++;
				t1.addStatement(s1);
				t1.addStatement(c1);
				ao1.addedInformation(true);
				doSetTheory(t1, false);
				showEdit(s1);
				support.setEnabled(false);
				attack.setEnabled(false);
			}
		}
		else if(e.getSource() == jbassumption)
		{
			if(selected != null)
			{
				selected.getArgObject().setArgumentType(Statement.ASSUMPTION);
				jbassumption.setEnabled(false);
				jbissue.setEnabled(true);
				//updateIcon();
				setTheory(t1);
			}	
		}
		else if(e.getSource() == jbissue)
		{
			if(selected != null)
			{
				selected.getArgObject().setArgumentType(Statement.ISSUE);
				jbassumption.setEnabled(true);
				jbissue.setEnabled(false);
				//updateIcon();
				setTheory(t1);
			}
		}
		else if (e.getSource() == buttonSubmit)
		{
			System.out.println("BOE!");
		    ArgObject ao1 = selected.getArgObject();
		    if (ao1.evaluate(t1) != Statement.EVALUATION_UNKNOWN)
		    	return;
		    if (rbutDefeated.isSelected())
		    	ao1.setEvaluation(Statement.EVALUATION_DEFEATED);
		    if (rbutUndefeated.isSelected())
		    	ao1.setEvaluation(Statement.EVALUATION_UNDEFEATED);
		    frameCS.setVisible(false);
		    setTheory(t1);
		    
		}   
		else
		{
			if(e.getActionCommand().equals("attacker"))
			{
				System.out.println("adding attacker");
				if(selected != null)
				{
					ArgObject ao1 = selected.getArgObject();
					Statement s1 = new Statement();
					s1 = createAndSetName(s1);
					Conditional c1 = new Conditional(s1,ao1.getNegation());
					c1.setName(startConditionName + "");
					startConditionName++;
					t1.addStatement(s1);
					t1.addStatement(c1);
					ao1.addedInformation(true);
					doSetTheory(t1, false);
					showEdit(s1);
				}
			}
			else if(e.getActionCommand().equals("supporter"))
			{
				System.out.println("adding supporter");
				if(selected != null)
				{
					ArgObject ao1 = selected.getArgObject();
					Statement s1 = new Statement();
					s1 = createAndSetName(s1);
					Conditional c1 = new Conditional(s1,ao1);
					c1.setName(startConditionName + "");
					startConditionName++;
					t1.addStatement(s1);
					t1.addStatement(c1);
					ao1.addedInformation(true);
					doSetTheory(t1, false);
					showEdit(s1);
				}		  		
			}
			else if(e.getActionCommand().equals("makeAssumption"))
			{
				if(selected != null)
				{
					//System.out.println("makingassumption");
					ArgObject ao1 = selected.getArgObject();
					ao1.setArgumentType(Statement.ASSUMPTION);
					jbassumption.setEnabled(false);
					jbissue.setEnabled(true);
					//updateIcon();
					setTheory(t1);
				}
			}
			else if(e.getActionCommand().equals("makeIssue"))
			{
				if(selected != null)
				{
					//System.out.println("makingISSUE");
					ArgObject ao1 = selected.getArgObject();
					ao1.setArgumentType(Statement.ISSUE);
					jbassumption.setEnabled(true);
					jbissue.setEnabled(false);
					updateIcon();
				}
			}
			else if(e.getActionCommand().equals("RemoveStatement"))
			{
				if(selected != null)
				{
					if(selected instanceof VisualArgObject)
					{
						jbassumption.setEnabled(false);
						jbissue.setEnabled(false);
						support.setEnabled(false);
						attack.setEnabled(false);	
						
						VisualArgObject vao1 = (VisualArgObject)selected;
						ArgObject[] statements = t1.getStatements();
						if(vao1.isRecursive())
						{
							for(int i = 0; i < statements.length;i++)
							{
								if(statements[i] instanceof Conditional)
								{
									Conditional c1 = (Conditional)statements[i];
									if(c1.isAntecedent_isRecursive())
									{
										ArgObject[] antecendent = c1.getAntecedents();
										if(findInList(antecendent,vao1.getArgObject(),true) != -1)
										{
											System.out.println("removed recursive path");
											t1.removeStatement(c1);
										}
									}
								}
							}
						}
						else
						{
							for(int i = 0; i < statements.length;i++)
							{
								if(statements[i] instanceof Conditional)
								{
									Conditional c1 = (Conditional)statements[i];
									if(!c1.isAntecedent_isRecursive())
									{
										ArgObject[] antecendent = c1.getAntecedents();
										int index = -1;
										if((index = findInList(antecendent,vao1.getArgObject(),true)) != -1)
										{
											System.out.println("removed antecedent");
											t1.removeAllChildConditionals(c1);
											t1.removeStatement(c1);
										}
										else if(c1.getConsequent() == vao1.getArgObject() || c1.getConsequent().getNegation() == vao1.getArgObject())
										{
											System.out.println("removed for Consequent");
											t1.removeAllChildConditionals(c1);
											t1.removeStatement(c1);
										}
									}
								}
							}		
							System.out.println("removed Statement self");
							t1.removeStatement(vao1.getArgObject());
						}
						
						doSetTheory(t1, true);				
					}
				}
			}
			else if(e.getActionCommand().equals("SolveConflict"))
			{
				ArgObject ao1 = selected.getArgObject();
				
				// Check if there are supporters or attackers with EVALUATION_UNKNOWN
				// If so, it would be advisable to solve other conflicts first
				boolean lowerUnknownEvalFound = false;
				ArgObject attackers[] = ao1.getAttackers();
				for (int i = 0; i < attackers.length; i++)
				{
					if (attackers[i].evaluate(t1) == Statement.EVALUATION_UNKNOWN)
					{						
						Label attackerUnknown = new Label("De aanvallende stelling \"" + attackers[i].getText() + " heeft een onbekende waarde. \nLos eerst dat conflict op alvorens dit conflict op te lossen");
						frameCSWarning.getContentPane().add(attackerUnknown, BorderLayout.CENTER);
						
						frameCSWarning.setLocation(700,500);
						frameCSWarning.pack();
						frameCSWarning.setVisible(true);
						// Print window dat de stelling met inhoud zus en zo unknown is. Los eerst dat conflict op.
						lowerUnknownEvalFound = true;
						return;
					}	
				} // end go through attackers
				if (!lowerUnknownEvalFound)
				{
					ArgObject supporters[] = ao1.getSupporters();
					
					for (int i = 0; i < supporters.length; i++)
					{
						if (supporters[i].evaluate(t1) == Statement.EVALUATION_UNKNOWN)
						{
							Label supporterUnknown = new Label("De aanvallende stelling \"" + supporters[i].getText() + " heeft een onbekende waarde. \nLos eerst dat conflict op alvorens dit conflict op te lossen");
							frameCSWarning.getContentPane().add(supporterUnknown, BorderLayout.CENTER);
							
							frameCSWarning.setLocation(700,500);
							frameCSWarning.pack();
							frameCSWarning.setVisible(true);
							
							return;
							
						}
					}
				}
				if (!lowerUnknownEvalFound)
				{
					ArgObject attackingConditionals[] = ao1.getAttackingConditionals();
					
					for (int i = 0; i < attackingConditionals.length; i++)
					{
						if (attackingConditionals[i].evaluate(t1) == Statement.EVALUATION_UNKNOWN)
						{
							Label supporterUnknown = new Label("De aanvallende conditional \"" + attackingConditionals[i].getText() + " heeft een onbekende waarde. \nLos eerst dat conflict op alvorens dit conflict op te lossen");
							frameCSWarning.getContentPane().add(supporterUnknown, BorderLayout.CENTER);
							
							frameCSWarning.setLocation(700,500);
							frameCSWarning.pack();
							frameCSWarning.setVisible(true);
							
							return;
							
						}
					}
				}
				if (!lowerUnknownEvalFound)
				{
					ArgObject supportingConditionals[] = ao1.getSupportingConditionals();
					
					for (int i = 0; i < supportingConditionals.length; i++)
					{
						if (supportingConditionals[i].evaluate(t1) == Statement.EVALUATION_UNKNOWN)
						{
							Label supporterUnknown = new Label("De ondersteunende conditional \"" + supportingConditionals[i].getText() + " heeft een onbekende waarde. \nLos eerst dat conflict op alvorens dit conflict op te lossen");
							frameCSWarning.getContentPane().add(supporterUnknown, BorderLayout.CENTER);
							
							frameCSWarning.setLocation(700,500);
							frameCSWarning.pack();
							frameCSWarning.setVisible(true);
							
							return;
							
						}
					}
				}
				// Supporters and attackers are all known and defined. Conflict solving may proceed.	
				
				
				infoPanel.add(labelGiveValue);			
				dataPanel.add(rbutUndefeated);
				dataPanel.add(rbutDefeated);
				butgroupDefeasibility.add(rbutUndefeated);
				butgroupDefeasibility.add(rbutDefeated);
				buttonSubmit.addActionListener(this);
				submitPanel.add(buttonSubmit);
				
				frameCS.getContentPane().setLayout(new FlowLayout());
				frameCS.getContentPane().add(infoPanel);
				frameCS.getContentPane().add(dataPanel);
				frameCS.getContentPane().add(submitPanel);
				
				frameCS.setLocation(700,500);
				frameCS.pack();
				frameCS.setVisible(true);

		 	} // end action "SolveConflict"
		}
	}


	
	private Statement createAndSetName(Statement s1)
	{
	
			   char name = 'a';
			   for (int checkIdx = 0; checkIdx < t1.getStatements().length; checkIdx++)
			   {				
				   System.out.println("In loop. " + checkIdx + ": hasName: " + t1.getStatements()[checkIdx].hasName());
					if (t1.getStatements()[checkIdx].hasName()){
						System.out.println("Name in existence: " + t1.getStatements()[checkIdx].getName());
					    System.out.println("Name to be designated: " + name);
						if (t1.getStatements()[checkIdx].getName().equals(name + ""))
						{
							   System.out.println("Al bezet");
							   name++;
							   checkIdx = -1;
							   continue;
						}
				     }
		   		}
			   System.out.println("Set name: is " + name);
			   s1.setName(name+"");
			   //System.out.println("Has name now? " + t1.getStatements()[i].hasName());
			   
	
	   return  s1;
	}
	
	protected int findInList(ArgObject[] list, ArgObject element,boolean includeNegation)
	{
		boolean found = false;
		int i =0;
		int rt = -1;
		
		while(!found && i < list.length)
		{
			if(list[i]== element || list[i].getNegation() == element) { rt=i; found = true;}
			i++;
		}
		return rt;
	}	
	private void showEdit(ArgObject ao1)
	{
		boolean found = false;
		int i =0;
		while(!found && i < visObjects.length)
		{
			if(visObjects[i].getArgObject() ==ao1)
			{
				found = true;
				Rectangle r1 = visObjects[i].getBounds();
				//int xScrolled = (this.horizontalScrollBar.getValue());
				int yScrolled = (this.verticalScrollBar.getValue());
				
				int maxY = r1.y + r1.height;
				if(maxY > getHeight() + yScrolled)
				{
					this.verticalScrollBar.setValue(this.verticalScrollBar.getMaximum());
				}
				
				showEdit(visObjects[i]);
				selected = visObjects[i];
				
			}
			i++;
		}
	}
	
	private void doSetTheory(Theory t1, boolean scrollToTopRight )
	{
		System.out.println("Rebuild visual");
		switch(useVOTreeMaker)
		{
			case 2:
				VOTreeMaker2 vot2;
				vot2 = new VOTreeMaker2();
				visObjects = vot2.makeTreeFromTheory(t1,(Graphics2D)this.getGraphics());
				//visObjects = vot2.makeTreeFromTheory(t1);	
			break;
			default:
				VOTreeMaker vot1;
				vot1 = new VOTreeMaker();
				visObjects = vot1.makeTreeFromTheory(t1);		
			break;
		}
		
		//System.out.println("updated Theory!");
		this.t1 = t1;
		t1.evaluate();
		updateArgumentEvaluation();
		Rectangle r1;
		int maxX = 0;
		int maxY = 0;
		Graphics2D g2 = (Graphics2D)getGraphics();
		if(	visObjects != null)
		{	
			for(int i =0; i < visObjects.length; i++)
			{
				if(visObjects[i] instanceof VisualArgObject)
				{
					
					visObjects[i].draw(g2,t1);
					r1 = visObjects[i].getBounds();
					if((r1.x + r1.width) > maxX) maxX = (r1.x + r1.width);
					if((r1.y + r1.height) > maxY) maxY = (r1.y + r1.height);
				}
			}
		}
		
		//System.out.println("maxx" + maxX + " " + maxY);
		imageMinimumDimension = new Dimension(maxX +50, maxY + 50);
		updateIcon();	
		
		jta1.setText(t1.toString());

		if(scrollToTopRight)
		{
			verticalScrollBar.setValue(0);
			horizontalScrollBar.setValue(0);
		}
	}
	
	public void setTheory(Theory t1)
	{
		
		t1.evaluate();
		doSetTheory(t1, true);
		jsp1.setVisible(false);
		support.setEnabled(false);
		attack.setEnabled(false);
		jbassumption.setEnabled(false);
		jbissue.setEnabled(false);
		selected = null;
	}
	
	public void lostFocus()
	{
		selected = null;
	}
	
	private void addVisualObject(VisualObject vo1)
	{
		if(visObjects == null)
		{	
			visObjects = new VisualObject[1];
			visObjects[0] = vo1;
		}
		else
		{
			VisualObject[] dum = new VisualObject[visObjects.length +1];
			for(int i =0; i < visObjects.length; i++)
				dum[i] = visObjects[i];
			dum[visObjects.length] = vo1;
			visObjects=dum;
		}
	}
	
	private void enterPressed()
	{
		if(selected != null && selected instanceof VisualArgObject)
		{
			VisualArgObject vao1 = (VisualArgObject)selected;
			ArgObject a1 = vao1.getArgObject();
			a1.setText(jtf.getText());
			String[] data = jtf.getText().split("\n");
			if(data.length != vao1.getLines() || useVOTreeMaker ==2)
			{
				doSetTheory(t1,false);
				jsp1.setVisible(false);
			}
			else
			{
				vao1.newTextSet();
				vao1.setDrawText(true);
				jsp1.setVisible(false);
				updateIcon();
			}
		}
	}
	
	
	public void mouseExited(MouseEvent e) {}
	public void mouseEntered(MouseEvent e){}
	public void mouseReleased(MouseEvent e) {}
	public void mouseClicked(MouseEvent e) {}
	public void mousePressed(MouseEvent e)
	{		
		int xScrolled = (this.horizontalScrollBar.getValue());
		int yScrolled = (this.verticalScrollBar.getValue());
		if(e.getButton() == 1)
		{
			if(visObjects != null)
			{
				deHighLight();
				boolean found = false;
				int i =0;
				while(!found && i < visObjects.length)
				{
					if(visObjects[i].contains(e.getX() + xScrolled,e.getY() + yScrolled))
					{
						found =true;
						if(jsp1.isVisible())
						{
							if(!selected.equals(visObjects[i])) enterPressed();
							visObjects[i].doHighlight();
							selected = visObjects[i];	
						}
						else
						{
							if(!visObjects[i].isHighlighted())
							{
								visObjects[i].doHighlight();
								selected = visObjects[i];
								support.setEnabled(true);
								attack.setEnabled(true);
								boolean assumption = false;
								boolean issue = false;
								
								if(visObjects[i].getArgObject().getArgumentType() != Statement.ASSUMPTION)
									assumption = true;
								if(visObjects[i].getArgObject().getArgumentType() != Statement.ISSUE)
									issue = true;
								jbassumption.setEnabled(assumption);
								jbissue.setEnabled(issue);
								
							}
						}
						if(visObjects[i].equals(selected) && (e.getClickCount() >= 2))showEdit(visObjects[i]);
					}
					i++;
				}
				
				if(!found && jsp1.isVisible()) enterPressed();
				else if (!found)
				{
					support.setEnabled(false);
					attack.setEnabled(false);
					jbassumption.setEnabled(false);
					jbissue.setEnabled(false);
					selected = null;
				}
				updateIcon();
			}
		}
		else if(e.getButton() == 3)
		{			
			if(selected != null && !jsp1.isVisible() && visObjects != null)
			{
				if(showTooltip)
				{	
					showTooltip = false;
					updateIcon();	
				}
				boolean found = false;
				int i =0;
				while(!found && i < visObjects.length)
				{
					if(visObjects[i].contains(e.getX() + xScrolled,e.getY() + yScrolled))
					{
						
						found =true;
						if(visObjects[i] == selected)
						{		
							boolean recursive = false;
							if(visObjects[i] instanceof VisualArgObject)
							{
								if(((VisualArgObject)visObjects[i]).isRecursive())
								{
									recursive = true;
								}
							}
							fillPopupMenu(selected.getArgObject(), recursive);
							jpm1.show(this,e.getX() ,e.getY()) ;
						}
					}
					i++;
				}
				
			}
		}
	}
	
	private void showEdit(VisualObject o1)
	{
		if(o1 instanceof VisualArgObject)
		{
			
			VisualArgObject vao1 = (VisualArgObject)o1;
			
			if(!vao1.isRecursive())
			{
				Rectangle r1 = vao1.getRectangle();
				ArgObject a1 = vao1.getArgObject();
				Rectangle r2 = new Rectangle(r1);
				
				int xScrolled = (this.horizontalScrollBar.getValue());
				int yScrolled = (this.verticalScrollBar.getValue());
				r2.x -= xScrolled - vao1.getTextIndentX();
				r2.y -= yScrolled;
				r2.y += 2;
				if(r2.height == 40) r2.y+=9;
				if(r2.width < 300) r2.width = 300;
				//if((r2.x + r2.width) > getWidth()) r2.width = getWidth() - r2.x;
				jtf.setText(a1.getUnparsedText());
				jsp1.setBounds(r2);
				jsp1.setVisible(true);
				jtf.selectAll();
				vao1.setDrawText(false);
				//selected = o1;
				updateIcon();
				//repaint();
				this.requestFocus();
				jtf.requestFocus();
			}
		}
	}
	
	private void deHighLight()
	{
		if(visObjects != null)
		{
			for(int i=0; i < visObjects.length; i++)
			{
				visObjects[i].deHighLight();
			}
		}
	}
	
	
	private void updateIcon()
	{
		long time = System.currentTimeMillis();
		//BufferedImage image = new BufferedImage(getWidth(),
		//		 getHeight(),BufferedImage.TYPE_INT_ARGB);
		
		int width =0;
		int height=0;
		if(imageMinimumDimension != null)
		{
			//System.out.println("dimension=" + imageMinimumDimension.width + " " + imageMinimumDimension.height);
			width = imageMinimumDimension.width;
			height =  imageMinimumDimension.height;			
		}
		
		if(width < getWidth()) width = getWidth();
		if(height < getHeight()) height = getHeight();
		//System.out.println("" + width + " " + height);
		if(width != image.getWidth() || height != image.getHeight() )
		{
			image = new BufferedImage(width,
					height,BufferedImage.TYPE_INT_ARGB);
		}
		paintIcon(image.getGraphics());
		i1 = new ImageIcon(image);
		jl1.setIcon(i1);
		repaint();
		System.out.println("time to paint icon(whole tree):" + (System.currentTimeMillis() - time) + "msec.");
	}
	
	public void updateArgumentEvaluation()
	{
		if (visObjects != null)
		{
			for(int i = 0; i < visObjects.length; i++)
			{
				if (visObjects[i] instanceof VisualArgObject)
				{
					VisualArgObject va1 = (VisualArgObject)visObjects[i];
					va1.updateEvaluation(t1);
				}
			}
		}
	}
	public void paintIcon(Graphics g)
	{
		Graphics2D g2 = (Graphics2D)g;
		g2.setColor(Color.white);
		g2.fillRect(0,0,image.getWidth(),image.getHeight());
		
		//g2.drawImage(images[0].getImage(),150,10,null);
		
		if(visObjects != null)
		{
			for(int i =0; i < visObjects.length;i++)
			{

				visObjects[i].draw(g2,t1);
				if(visObjects[i] instanceof VisualArgObject)
				{
					VisualArgObject va1 = (VisualArgObject)visObjects[i];
					int type = -1;
					int x = va1.getRectangle().x;
					int y = va1.getRectangle().y;
					if(va1.getArgObject().getArgumentType() == Statement.ASSUMPTION)
						type = 1;
					else if(va1.getArgObject().getArgumentType() == Statement.ISSUE)
						type = 0;
					if(type != -1)
						g2.drawImage(images[type].getImage(),x + 16,y + 6,null);
					
					/*
					if(t1 != null)
					{
						int eval = ((VisualArgObject)visObjects[i]).updateEvaluation(t1);	
						g2.setColor(Color.black);
						g2.fillRoundRect(x + 5,y + 6,10,24,5,6);
						System.out.println("Text: " + va1.getArgObject().getText() + ". Eval: " + eval);
						if(eval == ArgObject.EVALUATION_DEFEATED )
							g2.setColor(redLight);
						else
							g2.setColor(redDark);							
						g2.fillOval(x + 7,y + 8,6,6);
						if(eval == ArgObject.EVALUATION_UNKNOWN)
							g2.setColor(orangeLight );
						else
							g2.setColor(orangeDark);
						g2.fillOval(x + 7,y + 15,6,6);
						if(eval == ArgObject.EVALUATION_UNDEFEATED)
							g2.setColor(greenLight );
						else
							g2.setColor(greenDark);
						g2.fillOval(x + 7,y + 22,6,6);
					}
					*/
				}
			}
			if(!tooltip.equals("") && showTooltip && mousePoint!= null)
			{
				g2.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER , 10,null,0));
				int xScrolled = (this.horizontalScrollBar.getValue());
				int yScrolled = (this.verticalScrollBar.getValue());	
				g2.setColor(tooltipColor);
				String[] data = tooltip.split("\n");
				String test = "";
				for(int i =0; i < data.length;i++)
				{
					if(data[i].length() > test.length()) test = data[i];
				}
				Rectangle2D r2 = g2.getFontMetrics().getStringBounds(test,0,test.length(),g2 );
				
				int width = (int)r2.getWidth() + 40;
				g2.fillRect(mousePoint.x + 15 + xScrolled,mousePoint.y + 10 + yScrolled,width,13 * data.length);
				g2.setColor(Color.black);
				g2.drawRect(mousePoint.x + 15+ xScrolled,mousePoint.y+ 10 + yScrolled,width,13* data.length);				
				for(int i =0; i < data.length; i++)
					g2.drawString(data[i],mousePoint.x + 18 + xScrolled,mousePoint.y + 22 + (i*12)+ yScrolled);
			}
		}
	}
	
	private void redrawPanel()
	{
		long time = System.currentTimeMillis();
			
		int widthPanel = 0;
		int heightPanel = 0;
		
		// Wat doet dit?
		if(imageMinimumDimension != null)
		{
			//System.out.println("dimension=" + imageMinimumDimension.width + " " + imageMinimumDimension.height);
			widthPanel = imageMinimumDimension.width;
			heightPanel =  imageMinimumDimension.height;			
		}
		
		// Waarom deze check?
		if(widthPanel < getWidth()) widthPanel = getWidth();
		if(heightPanel < getHeight()) heightPanel = getHeight();
		
		if(widthPanel != image.getWidth() || heightPanel != image.getHeight() )
		{
			System.out.println("Create image with new size");
			image = new BufferedImage(widthPanel,
					heightPanel,BufferedImage.TYPE_INT_ARGB);
		}
		Graphics2D g = (Graphics2D) image.getGraphics();
		
	    System.out.println("VisualJPanel: breedte: " + image.getWidth() + " lengte: " + image.getHeight());
		g.setColor(Color.white);
		g.fillRect(0,0,image.getWidth(),image.getHeight());
		
		//g2.drawImage(images[0].getImage(),150,10,null);
		if (visObjects == null)
			System.out.println("Geen visualArgObjects");
		if(visObjects != null)
		{
			for(int i = 0; i < visObjects.length; i++)
				visObjects[i].draw(g, t1);
			
			if(!tooltip.equals("") && showTooltip && mousePoint!= null)
			{
				g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER , 10,null,0));
				int xScrolled = (this.horizontalScrollBar.getValue());
				int yScrolled = (this.verticalScrollBar.getValue());	
				g.setColor(tooltipColor);
				String[] data = tooltip.split("\n");
				String test = "";
				for(int i =0; i < data.length;i++)
				{
					if(data[i].length() > test.length()) test = data[i];
				}
				Rectangle2D r2 = g.getFontMetrics().getStringBounds(test,0,test.length(),g );
				
				int widthx = (int)r2.getWidth() + 40;
				g.fillRect(mousePoint.x + 15 + xScrolled,mousePoint.y + 10 + yScrolled,widthx,13 * data.length);
				g.setColor(Color.black);
				g.drawRect(mousePoint.x + 15+ xScrolled,mousePoint.y+ 10 + yScrolled,widthx,13* data.length);				
				for(int i =0; i < data.length; i++)
					g.drawString(data[i],mousePoint.x + 18 + xScrolled,mousePoint.y + 22 + (i*12)+ yScrolled);
			}
		}
		i1 = new ImageIcon(image);
		jl1.setIcon(i1);
		repaint();
		System.out.println("time to paint icon(whole tree):" + (System.currentTimeMillis() - time) + "msec.");
	}
}




